﻿using ComLib.ComType;
using KInterfaces;
using KXmlUIControl;
using LogLib;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;

namespace KFormBase
{
    public class ModuleAppManager : Singleton<ModuleAppManager>
    {
        #region static Fields and Functions
        public static string XmlConfigFolder = "";
        static ModuleAppManager()
        {
            string directory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
            directory = directory.Substring(6);
            StaticTypes.SetRootDirectory(directory);
            XmlConfigFolder = directory + @"\config";
        }
        #endregion

        public List<XmlModuleObject> Modules { get; private set; } = new List<XmlModuleObject>();

        public List<XmlProgramObject> Programs { get; private set; } = new List<XmlProgramObject>();

        public Dictionary<string, ModuleApplication> DicModuleApps = new Dictionary<string, ModuleApplication>();

        private ShareDataManager _sdm = null;

        public XmlConfigApplication AppConfig { get; private set; } = null;

        protected string _xmlConfigFile = "";
        public string AppName { get; private set; }

        /// <summary>
        /// 最新错误信息
        /// </summary>
        public string Error { get; private set; }

        public ModuleApplication DefaultApp
        {
            private set;
            get;
        }

        public ModuleApplication HomeApp
        {
            private set;
            get;
        }

        public ModuleApplication StartupApp
        {
            private set;
            get;
        }

        public ModuleAppManager()
        {
            _sdm = ShareDataManager.Instance;
        }

        public ModuleApplication this[string name]
        {
            get 
            {
                if (DicModuleApps.ContainsKey(name))
                {
                    return DicModuleApps[name];
                }
                else
                {
                    throw new Exception("未找到应用程序模块:" + name);
                }               
            }
        }

        private bool LoadConfig()
        {
            Log.WriteAsync("LoadConfig in");
            _xmlConfigFile = string.Format(@"{0}\{1}.xml", XmlConfigFolder, AppName);
            if (!File.Exists(_xmlConfigFile))
            {
                Error = $"XmlConfigFile={_xmlConfigFile} is not exists.";
                Log.WriteAsync(Error);
                return false;
            }
            AppConfig = new XmlConfigApplication(_xmlConfigFile);
            if (!AppConfig.OnReading())
            {
                Error = AppConfig.Error;
                Log.WriteAsync(Error);
                return false;
            }
            Modules = AppConfig.ListModules;
            Programs = AppConfig.ListPrograms;  
            ShareDataManager.GlobalData.SetValue("Programs", Programs);
            Log.WriteAsync("LoadConfig out");
            return true;
        }

        private bool CreatModuleApplications()
        {
            foreach (XmlModuleObject config in Modules)
            {
                ShareData data = _sdm.Add(config.Name);
                ModuleApplication app = new ModuleApplication(data, config);
                if (app.Init())
                { 
                    DicModuleApps.Add(config.Name, app);
                }
                else
                {
                    Error = app.Error;
                    return false;
                }
            }
            return true;
        }

        public void AddAppsEventHandler(
            ModulePageChangeEventHandler handlerMPC, 
            ModuleAppSwitchedEventHandler handlerMAS,
            EventHandler handlerExit,
            EventHandler handlerRequestExit,
            TakeAdministratorActionEventHandler takeAdminAction,
            JobStateChangedEventHandler jobStateChanged)
        {
            ModuleApplication[] apps = DicModuleApps.Values.ToArray();
            for (int i = 0; i < apps.Length; i++)
            {
                ModuleApplication app = apps[i];
                app.ModulePageChanged += handlerMPC;
                app.ModuleAppSwitched += handlerMAS;
                app.AppExitRequested += handlerRequestExit;
                app.AppExited += handlerExit;
                app.AdminActionTaken += takeAdminAction;
                app.ModuleManager = this;
                app.JobStateChanged += jobStateChanged;
            }
        }

        public bool Init(string appName)
        {
            AppName = appName;
            try
            {
                if (LoadConfig())
                {
                    if (CreatModuleApplications())
                    {
                        if (DicModuleApps.ContainsKey(AppConfig.HomeAppName))
                        {
                            HomeApp = DicModuleApps[AppConfig.HomeAppName];
                        }
                        if (DicModuleApps.ContainsKey(AppConfig.StartupAppName))
                        {
                            StartupApp = DicModuleApps[AppConfig.StartupAppName];
                        }
                        if (DicModuleApps.ContainsKey(AppConfig.DefaultAppName))
                        {
                            DefaultApp = DicModuleApps[AppConfig.DefaultAppName];
                        }
                        return true;
                    }
                }
                return false;
            }
            catch (Exception ex)
            {
                Log.WriteExceptionAsync(ex.ToString());
                Error = $"系统初始化发生了异常: {ex.Message}";
                return false;
            }
        }

        public void Exit()
        {
            ModuleApplication[] array = DicModuleApps.Values.ToArray();
            for (int i = 0; i < array.Length; i++ )
            {
                array[i].Dispose();
            }
        }
    }
}
